// 位于playPage内部, 显示和控制歌词滚动的模块
<template>
  <div class="scroller" ref="scroller">
    <div>
      <div class="place-holder"></div>
      <div class="sentence" v-for="(lyric, index) in parsedLyric" :key="index" :sindex="index">
        <p class="text" v-for="(content, index) in lyric.contents" :key="index">
          {{ content }}
        </p>
      </div>
      <div class="empty" v-if="!parsedLyric.length">抱歉, 还没有歌词</div>
      <div class="place-holder"></div>
    </div>
  </div>
</template>

<script>
import { ref, watch, watchEffect, nextTick, computed } from "vue"
import { useStore } from "vuex"
import BScroll from "@better-scroll/core"
import ScrollBar from "@better-scroll/scroll-bar"
import MouseWheel from "@better-scroll/mouse-wheel"
BScroll.use(ScrollBar)
BScroll.use(MouseWheel)
// betterscroll的基本设置
const defaultOptions = {
  mouseWheel: true,
  scrollY: true,
  scrollbar: true,
  probeType: 3,
}
// 恢复自动滚动的定时器时间
const AUTO_SCROLL_RECOVER_TIME = 2000

export default {
  props: {
    parsedLyric: Array,
    options: {
      type: Object,
      default: () => [],
    },
  },
  setup(props) {
    let store = useStore()
    let currentTime = computed(() => store.state.music.currentTime)
    let scroller = ref(null)
    // betterscroll实例
    let bs
    // 是否自动滚动  如果用户使用了鼠标滚轮,那就等待2秒再继续自动滚动
    let autoScroll = true

    // 监视props.parsedLyric, 歌词变化时视情况创建或者刷新betterscroll
    watchEffect(() => {
      if (props.parsedLyric.length) {
        createBS()
      }
    })

    function createBS() {
      nextTick(() => {
        // 页面第一次加载
        if (!bs) {
          bs = new BScroll(scroller.value, Object.assign({}, defaultOptions, props.options))
          // 修改一下滚动条的样式
          const bscrollIndicator = document.querySelector(".bscroll-indicator")
          bscrollIndicator.style.setProperty("border", "none")
          bscrollIndicator.style.setProperty("background", "var(--scrollbar-color)")
          _initScroller(bs)
        } else {
          bs.refresh()
        }
      })
    }

    function _initScroller(scoller) {
      function onScrollStart() {
        autoScroll = false
      }
      function onScrollEnd() {
        clearTimeout(bs.timer)
        bs.timer = setTimeout(() => {
          autoScroll = true
        }, AUTO_SCROLL_RECOVER_TIME)
      }
      // 如果用户使用鼠标拖动或者滚轮滚动歌词, 就等待2秒后再自动滚动
      scoller.on("scrollStart", onScrollStart)
      scoller.on("mousewheelStart", onScrollStart)

      scoller.on("scrollEnd", onScrollEnd)
      scoller.on("mousewheelEnd", onScrollEnd)
    }

    // 监视currentTime, 根据当前时间找到对应的那句歌词
    let activeLyricIndex = ref(null)
    let showPlayPage = computed(() => store.state.music.showPlayPage)
    watch(currentTime, (newValue) => {
      // currentTime变化时,歌词可能还没下载好,bs可能还没创建
      if (!props.parsedLyric.length || !bs || !showPlayPage.value) {
        activeLyricIndex.value = null
        return
      }
      activeLyricIndex.value = props.parsedLyric.findIndex((l, index) => {
        const nextLyric = props.parsedLyric[index + 1]
        // 如果有下一句歌词
        if (nextLyric) {
          return l.time <= newValue && nextLyric.time > newValue
        }
        // 如果没有下一句歌词,那么当前歌词为最后一句
        else {
          return true
        }
      })
    })

    let lastActiveLyric
    // 监视 active的那句歌词,给对应的div加上.active类
    watch(activeLyricIndex, (newValue) => {
      // 如果切歌,那么activeLyricIndex的值将会变成null
      if (newValue === null) return

      // 把之前的active歌词的active类去掉
      if (lastActiveLyric) {
        lastActiveLyric.classList.remove("active")
      }

      // 获取应该active的歌词所在的div
      const activeLyric = document.querySelector(`.sentence[sindex='${newValue}']`)
      if (activeLyric) {
        activeLyric.classList.add("active")
        lastActiveLyric = activeLyric

        // 如果自动滚动处于开启状态, 就滚动到active的歌词
        if (autoScroll) {
          bs.scrollToElement(activeLyric, 200, 0, true)
        }
      }
    })

    return { scroller }
  },
}
</script>

<style lang="less" scoped>
.scroller {
  position: relative;
  height: 100%;
  overflow: hidden;
  .sentence {
    margin-bottom: 16px;
    font-size: @font-size-sm;
    &.active {
      font-size: @font-size;
      color: var(--font-color-white);
      font-weight: @font-weight-bold;
    }
    .text {
      margin-bottom: 8px;
    }
  }
  .place-holder {
    width: 100%;
    height: 120px;
  }
  .custom-indicator {
    border: none !important;
    background: var(--scrollbar-color) !important;
  }
}
</style>
